/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#ifndef DME_NAS_UTILITIES_H
#define DME_NAS_UTILITIES_H

#include <string>
#include <set>
#include <shared_mutex>
#include <ctime>
#include <iostream>
#include <sstream>
#include <boost/asio.hpp>
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/functional/hash.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include "define/Types.h"
#include "common/CleanMemPwd.h"

#ifndef BOOST_ASIO_DISABLE_STD_ALIGNED_ALLOC
#define BOOST_ASIO_DISABLE_STD_ALIGNED_ALLOC
#endif

namespace PluginUtils {
    constexpr uint8_t NUMBER0  = 0;
    constexpr uint8_t NUMBER1  = 1;
    constexpr uint8_t NUMBER2  = 2;
    constexpr uint8_t NUMBER3  = 3;
    constexpr uint8_t NUMBER4  = 4;
    constexpr uint8_t NUMBER5  = 5;
    constexpr uint8_t NUMBER6  = 6;
    constexpr uint8_t NUMBER7  = 7;
    constexpr uint8_t NUMBER8  = 8;
    constexpr uint8_t NUMBER10  = 10;
    constexpr uint8_t NUMBER15  = 15;
    constexpr uint8_t NUMBER22  = 22;
    constexpr uint8_t NUMBER25  = 25;
    constexpr uint8_t NUMBER30  = 30;
    constexpr uint8_t NUMBER50  = 50;
    constexpr uint8_t NUMBER60  = 60;
    constexpr uint8_t NUMBER64  = 64;
    constexpr uint8_t NUMBER75  = 75;
    constexpr uint8_t NUMBER80  = 80;
    constexpr uint8_t NUMBER100  = 100;
    constexpr uint8_t NUMBER180  = 180;
    constexpr uint16_t NUMBER256  = 256;
    constexpr uint32_t NUMBER1024 = 1024;
    constexpr uint32_t RETURNCODE6 = 6;
    constexpr uint32_t RETURNCODE7 = 7;
    constexpr uint32_t RETURNCODE28 = 28;
    constexpr uint32_t RETURNCODEMAX = 256;
    constexpr uint64_t RETRY_ERR_CODE = 1593987332;
    /**
    * protocol type passed in xxxx
    * We internally use GetProtocolType() api to change from RPC input type to the enum as expected by Data_Transmission
    */
    const std::string NAS_PROTOCOL_TYPE_E_CIFS = "0";
    const std::string NAS_PROTOCOL_TYPE_E_NFS = "1";
    
    struct CifsConnectParams {
        std::string domainName;
        std::string applicationId;
        std::string version;
        std::string shareName;
        std::string username;
        std::string password;
        std::string authType;
        std::string encryption;
        std::vector<std::string> nasServerIpList;

        ~CifsConnectParams()
        {
            Module::CleanMemoryPwd(password);
        }
    };
    struct NasMountParams {
        std::string protocol;
        std::string version;
        std::string sharePath;
        std::string localMountPath;
        std::string mountOptions;
        std::string username;
        std::string password;
        std::vector<std::string> nasServerIpList;
        NasMountParams(std::string proto, std::string vers, std::string path, std::string mountPoint,
            std::string opt, std::string user, std::string passwd, std::vector<std::string> ipList)
            : protocol(proto), version(vers), sharePath(path), localMountPath(mountPoint), mountOptions(opt),
            username(user), password(passwd), nasServerIpList(ipList) {}
        ~NasMountParams()
        {
            Module::CleanMemoryPwd(password);
        }
    };

    bool CheckDeviceNetworkConnect(const std::string &managerIps);
    std::string FormatTimeToStrBySetting(time_t timeInSeconds, const std::string& timeFormat);
    std::string FormatTimeToStr(time_t timeInSeconds);
    int KinitTGTInner(std::string userName, std::string password, std::string krb5Keytab,
        const std::string& krb5Conf, const std::string& uniqueFileJoinField);
    std::string Base64Encode(const std::string &in);
    std::string Base64Decode(const std::string &in);

    time_t GetCurrentTimeInSeconds();
    time_t GetCurrentTimeInSeconds(std::string &dateAndTimeString);
    std::string ConvertToReadableTime(time_t time);
    std::string GetPathName(const std::string &filePath);
    std::string GetFileName(const std::string &filePath);
    bool CreateDirectory(const std::string& path);
    bool Remove(std::string path);
    bool IsPathExists(const std::string &path);
    bool Rename(std::string srcPath, std::string dstPath);

    bool IsDirExist(const std::string& pathName);
    bool IsFileExist(const std::string& fileName);
    bool IsPigzExist();
    size_t GenerateHash(std::string jobId);
    std::string FormatCapacity(uint64_t capacity);
    std::string ConvertGBToBytes(const std::string& gbStr);
    std::string FloatToString(const float &val, const uint8_t &precisson = NUMBER1);
    std::string GetUniqueId();
    bool IsConnectIP(const std::string& ip);
    int CheckNfsAccessibility(const NasMountParams& param);
    int MountNFS(const NasMountParams& param, std::string &outSelectedSvcIp);
    int UnmountNas(std::string localPath);
    int CheckAndUnmount(std::string mountPath);
    bool PathExistMandate(const std::string &path);
    bool GetFileListInDirectory(const std::string &path, std::vector<std::string> &fileList);
    bool WriteFile(const std::string &filePath, std::vector<std::string>& fileContent);
    bool ReadFile(const std::string &filePath, std::vector<std::string>& fileContent);
    bool RemoveFile(const std::string &path);
    bool CopyFile(const std::string &srcPath, const std::string &destDir);
    bool RemoveDir(const std::string &dirName);
    bool RenameDir(const std::string &oldName, const std::string &newName);
    std::string FormatSpeed(uint64_t speed);
    bool RemoveDirectory(std::string path);
    std::string StripSqrBracketsFromIpAddress(const std::string &ipAddress);
    bool RecurseCreateDirectory(const std::string& path);
    // 获取部署类型， x6000 - d1, 防勒索 - d4, 安全一体机 - d5
    std::string GetDeployType();
    // 路径标准化函数， 去掉路径中多余的分隔符
    std::string StandardPath(const std::string& path);
    bool OperateIpsRule(const std::vector<std::string>& ipList, const std::string& operation);
    bool GetInnerPodIp(std::string& podIp);
    bool IsInnerAgent();
    void ResolveDomain(const std::string& domain, std::vector<std::string>& ipList);
    bool OperateIpsRuleForRemoteIp(const std::vector<std::string>& ipList, const std::string& operation,
                                   std::string& availableIp);
    uint32_t SafeStou32(const std::string& str);
    uint64_t SafeStou64(const std::string& str);
}

#endif  // DME_NAS_UTILITIES_H